/*
 * Copyright 2007 National Bioinformatics Network
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package dgbgui.actions;

import java.awt.event.ActionEvent;
import java.util.List;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;

import dgbgui.DGBGUI;

/**
 * Factory for action that will be used in the GUI
 * @author bjnortier
 *
 */
public class ActionFactory {
	

	/**
	 * @param actionName The action identifier
	 * @param properties The action properties, caption, description etc.
	 * @return The newly craeted abstract action
	 */
	public static AbstractAction createAction(ActionRepository.ActionName actionName,ActionRepository.ActionProperties properties) {

		
		/**
		 * Inner class to create an action class that extents the abstract action
		 * @author bjnortier
		 */
		class NewAction extends AbstractAction {
			
			private static final long serialVersionUID = 0L;
			private ActionRepository.ActionName m_actionName;

			NewAction(ActionRepository.ActionName actionName,ActionRepository.ActionProperties properties) {
				super(properties.getCaption());
				m_actionName = actionName;
				putValue(SHORT_DESCRIPTION,properties.getDescription());
                if ( properties.getAccelerator() !=null) {
                    putValue(ACCELERATOR_KEY , properties.getAccelerator());
                }
                if ( properties.getIconFileName() != null ) {
                    putValue(SMALL_ICON, DGBGUI.getIcon(properties.getIconFileName(),properties.getCaption()));
                    String smallFileName = properties.getIconFileName().replace(".png", "_small.png");
                    putValue("ACTUAL_SMALL_ICON", DGBGUI.getIcon(smallFileName,properties.getCaption()));
                }
			}
			
			/**
			 * Relay the action to the action proxy, which will handle acion
			 */
			public void actionPerformed(ActionEvent e) {
				ActionProxy.getInstance().actionInitiated(m_actionName);
			}
		}
		
		// Return an instance of the new Action class
		return new NewAction(actionName,properties);
	}

	
	/**
	 * Recursively create a JMenu from the ActionGroup
	 * @param group The ActionGroup to create the menu from
	 * @return The JMenu that was created
	 */
	public static JMenu createActionGroupMenu(ActionGroup group) {
		List<Object> actionsOrGroups = group.getActionsOrGroups();
		JMenu retMenu = new JMenu(group.getName());
		
		// If the object is an AbstractAction, create a JMenuItem for it,
		// otherwise create a submeny for the subgroup
		for (Object ob : actionsOrGroups) {
			assert ((ob instanceof AbstractAction) || (ob instanceof ActionGroup));
			if ( ob instanceof AbstractAction ) {
                JMenuItem menuItem = new JMenuItem((AbstractAction)ob);
                // No native support for small icons, so explicitly change the icon
                menuItem.setIcon((Icon)((AbstractAction)ob).getValue("ACTUAL_SMALL_ICON"));
				retMenu.add(menuItem);
			}
			else {
				retMenu.add(createActionGroupMenu((ActionGroup)ob));
			}
		}
		return retMenu;
	}
	
    /**
     * Create the menus
     */
    public static JMenuBar createMenuBar() {
        // Add all the actions to the menu bar
        JMenuBar menuBar = new JMenuBar();
        ActionRepository actionRepo = ActionRepository.getInstance();

        Set<ActionRepository.ActionGroupName> groupNames = actionRepo.getAllActionGroupNames();
        for ( ActionRepository.ActionGroupName groupName : groupNames ) {
            ActionGroup group =  actionRepo.getActionGroup(groupName);
            JMenu menu = ActionFactory.createActionGroupMenu(group);
            menuBar.add(menu);
        }
        return menuBar;
    }
    
    /**
     * Create the toolbars
     */
    public static JToolBar createToolBar(Set<ActionGroup> actionGroups) {
        
        JToolBar toolBar = new JToolBar();
        int index = 0;
        for ( ActionGroup group : actionGroups ) {
            // Separator between groups
            if ( index != 0 ) {
                toolBar.addSeparator();
            }
            // Add all the actions in a group
            for ( Object action : group.getActionsOrGroups() ) {
                assert ( action instanceof AbstractAction );
                toolBar.add((AbstractAction)action);
            }
            // For helping with seprators
            ++index;
        }
        return toolBar;
    }


	
}
